package com.sun.mail.pop3;

import com.sun.mail.util.LineInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.mail.FetchProfile;
import javax.mail.FetchProfile.Item;
import javax.mail.Flags;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.FolderClosedException;
import javax.mail.FolderNotFoundException;
import javax.mail.Message;
import javax.mail.MessageRemovedException;
import javax.mail.MessagingException;
import javax.mail.MethodNotSupportedException;
import javax.mail.UIDFolder.FetchProfileItem;

public class POP3Folder extends Folder {
    private boolean doneUidl = false;
    private boolean exists = false;
    private Vector message_cache;
    private String name;
    private boolean opened = false;
    private Protocol port;
    private int size;
    private int total;

    POP3Folder(POP3Store store, String name) {
        super(store);
        this.name = name;
        if (name.equalsIgnoreCase("INBOX")) {
            this.exists = true;
        }
    }

    public String getName() {
        return this.name;
    }

    public String getFullName() {
        return this.name;
    }

    public Folder getParent() {
        return new DefaultFolder((POP3Store) this.store);
    }

    public boolean exists() {
        return this.exists;
    }

    public Folder[] list(String pattern) throws MessagingException {
        throw new MessagingException("not a directory");
    }

    public char getSeparator() {
        return '\u0000';
    }

    public int getType() {
        return 1;
    }

    public boolean create(int type) throws MessagingException {
        return false;
    }

    public boolean hasNewMessages() throws MessagingException {
        return false;
    }

    public Folder getFolder(String name) throws MessagingException {
        throw new MessagingException("not a directory");
    }

    public boolean delete(boolean recurse) throws MessagingException {
        throw new MethodNotSupportedException("delete");
    }

    public boolean renameTo(Folder f) throws MessagingException {
        throw new MethodNotSupportedException("renameTo");
    }

    public synchronized void open(int mode) throws MessagingException {
        checkClosed();
        if (this.exists) {
            try {
                this.port = ((POP3Store) this.store).getPort(this);
                Status s = this.port.stat();
                this.total = s.total;
                this.size = s.size;
                this.mode = mode;
                this.opened = true;
                this.message_cache = new Vector(this.total);
                this.message_cache.setSize(this.total);
                this.doneUidl = false;
                notifyConnectionListeners(1);
            } catch (IOException e) {
                this.port = null;
                ((POP3Store) this.store).closePort(this);
            } catch (IOException ioex) {
                if (this.port != null) {
                    this.port.quit();
                }
                this.port = null;
                ((POP3Store) this.store).closePort(this);
            } catch (Throwable th) {
                Throwable th2 = th;
                this.port = null;
                ((POP3Store) this.store).closePort(this);
            }
        } else {
            throw new FolderNotFoundException((Folder) this, "folder is not INBOX");
        }
        return;
        throw new MessagingException("Open failed", ioex);
    }

    public synchronized void close(boolean expunge) throws MessagingException {
        checkOpen();
        try {
            if (((POP3Store) this.store).rsetBeforeQuit) {
                this.port.rset();
            }
            if (expunge && this.mode == 2) {
                for (int i = 0; i < this.message_cache.size(); i++) {
                    POP3Message m = (POP3Message) this.message_cache.elementAt(i);
                    if (m != null && m.isSet(Flag.DELETED)) {
                        this.port.dele(i + 1);
                    }
                }
            }
            this.port.quit();
            this.port = null;
            ((POP3Store) this.store).closePort(this);
            this.message_cache = null;
            this.opened = false;
            notifyConnectionListeners(3);
        } catch (IOException ioex) {
            throw new MessagingException("Exception deleting messages during close", ioex);
        } catch (IOException e) {
            this.port = null;
            ((POP3Store) this.store).closePort(this);
            this.message_cache = null;
            this.opened = false;
            notifyConnectionListeners(3);
        } catch (Throwable th) {
            Throwable th2 = th;
            this.port = null;
            ((POP3Store) this.store).closePort(this);
            this.message_cache = null;
            this.opened = false;
            notifyConnectionListeners(3);
        }
    }

    public boolean isOpen() {
        if (!this.opened) {
            return false;
        }
        if (this.store.isConnected()) {
            return true;
        }
        try {
            close(false);
            return false;
        } catch (MessagingException e) {
            return false;
        }
    }

    public Flags getPermanentFlags() {
        return new Flags();
    }

    public synchronized int getMessageCount() throws MessagingException {
        int i;
        if (this.opened) {
            checkReadable();
            i = this.total;
        } else {
            i = -1;
        }
        return i;
    }

    public synchronized Message getMessage(int msgno) throws MessagingException {
        POP3Message m;
        checkOpen();
        m = (POP3Message) this.message_cache.elementAt(msgno - 1);
        if (m == null) {
            m = createMessage(this, msgno);
            this.message_cache.setElementAt(m, msgno - 1);
        }
        return m;
    }

    protected POP3Message createMessage(Folder f, int msgno) throws MessagingException {
        POP3Message m = null;
        Constructor cons = ((POP3Store) this.store).messageConstructor;
        if (cons != null) {
            try {
                m = (POP3Message) cons.newInstance(new Object[]{this, new Integer(msgno)});
            } catch (Exception e) {
            }
        }
        if (m == null) {
            return new POP3Message(this, msgno);
        }
        return m;
    }

    public void appendMessages(Message[] msgs) throws MessagingException {
        throw new MethodNotSupportedException("Append not supported");
    }

    public Message[] expunge() throws MessagingException {
        throw new MethodNotSupportedException("Expunge not supported");
    }

    public synchronized void fetch(Message[] msgs, FetchProfile fp) throws MessagingException {
        int i;
        checkReadable();
        if (!this.doneUidl && fp.contains(FetchProfileItem.UID)) {
            String[] uids = new String[this.message_cache.size()];
            try {
                if (this.port.uidl(uids)) {
                    for (i = 0; i < uids.length; i++) {
                        if (uids[i] != null) {
                            ((POP3Message) getMessage(i + 1)).uid = uids[i];
                        }
                    }
                    this.doneUidl = true;
                }
            } catch (EOFException eex) {
                close(false);
                throw new FolderClosedException(this, eex.toString());
            } catch (IOException ex) {
                throw new MessagingException("error getting UIDL", ex);
            }
        }
        if (fp.contains(Item.ENVELOPE)) {
            for (POP3Message msg : msgs) {
                try {
                    msg.getHeader("");
                    msg.getSize();
                } catch (MessageRemovedException e) {
                }
            }
        }
    }

    public synchronized String getUID(Message msg) throws MessagingException {
        POP3Message m;
        checkOpen();
        m = (POP3Message) msg;
        try {
            if (m.uid == "UNKNOWN") {
                m.uid = this.port.uidl(m.getMessageNumber());
            }
        } catch (EOFException eex) {
            close(false);
            throw new FolderClosedException(this, eex.toString());
        } catch (IOException ex) {
            throw new MessagingException("error getting UIDL", ex);
        }
        return m.uid;
    }

    public synchronized int getSize() throws MessagingException {
        checkOpen();
        return this.size;
    }

    public synchronized int[] getSizes() throws MessagingException {
        int[] sizes;
        Throwable th;
        checkOpen();
        sizes = new int[this.total];
        InputStream is = null;
        LineInputStream lis = null;
        try {
            is = this.port.list();
            LineInputStream lis2 = new LineInputStream(is);
            while (true) {
                try {
                    String line = lis2.readLine();
                    if (line == null) {
                        break;
                    }
                    try {
                        StringTokenizer st = new StringTokenizer(line);
                        int msgnum = Integer.parseInt(st.nextToken());
                        int size = Integer.parseInt(st.nextToken());
                        if (msgnum > 0 && msgnum <= this.total) {
                            sizes[msgnum - 1] = size;
                        }
                    } catch (Exception e) {
                    }
                } catch (IOException e2) {
                    lis = lis2;
                } catch (Throwable th2) {
                    th = th2;
                    lis = lis2;
                }
            }
            if (lis2 != null) {
                try {
                    lis2.close();
                } catch (IOException e3) {
                }
            }
            if (is != null) {
                try {
                    is.close();
                    lis = lis2;
                } catch (IOException e4) {
                    lis = lis2;
                }
            }
        } catch (IOException e5) {
            if (lis != null) {
                try {
                    lis.close();
                } catch (IOException e6) {
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e7) {
                }
            }
            return sizes;
        } catch (Throwable th3) {
            th = th3;
            if (lis != null) {
                try {
                    lis.close();
                } catch (IOException e8) {
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e9) {
                }
            }
            throw th;
        }
        return sizes;
    }

    public synchronized InputStream listCommand() throws MessagingException, IOException {
        checkOpen();
        return this.port.list();
    }

    protected void finalize() throws Throwable {
        super.finalize();
        close(false);
    }

    void checkOpen() throws IllegalStateException {
        if (!this.opened) {
            throw new IllegalStateException("Folder is not Open");
        }
    }

    void checkClosed() throws IllegalStateException {
        if (this.opened) {
            throw new IllegalStateException("Folder is Open");
        }
    }

    void checkReadable() throws IllegalStateException {
        if (!this.opened || (this.mode != 1 && this.mode != 2)) {
            throw new IllegalStateException("Folder is not Readable");
        }
    }

    void checkWritable() throws IllegalStateException {
        if (!this.opened || this.mode != 2) {
            throw new IllegalStateException("Folder is not Writable");
        }
    }

    Protocol getProtocol() throws MessagingException {
        checkOpen();
        return this.port;
    }

    protected void notifyMessageChangedListeners(int type, Message m) {
        super.notifyMessageChangedListeners(type, m);
    }
}
